import pickle
from typing import List, Tuple

from async_task.models import Job, JobStatus, Task, TaskDepend


# todo job之间维护依赖关系

class AsyncTask:

    def __init__(self, name, task_kwargs=None, verify_kwargs=None):
        self.name = name
        self.task_kwargs = task_kwargs if task_kwargs else {}
        self.verify_kwargs = verify_kwargs if verify_kwargs else {}

    def __str__(self):
        return

    def task_impl(self, *args, **kwargs) -> Tuple[int, any]:
        """
        该方法为需要执行的任务实现
        必须返回一个元祖,第一个元素为int，0代表成功，其他代表失败
                       第二个元素为可被json序列化的对象，表示信息
        """
        return 0, ""

    def verify_impl(self, *args, **kwargs) -> Tuple[int, any]:
        """
        该方法为任务执行完成后的验证实现
        必须返回一个元祖,第一个元素为int，0代表成功，其他代表失败
                       第二个元素为可被json序列化的对象，表示信息
        """
        return 0, ""


def register_job(job_name, async_task_chains: List[List[AsyncTask]]):
    """
    job_name: job名称
    async_task_chains: 异步任务链，每个元素由一个异步任务层构成，每层包含多个AsyncTask
                       每层中的AsyncTask无依赖关系，并发执行
                       层与层之间存在依赖关系，下一层的执行依赖与上一层任务全部成功，上一层任务未全部成功，下层不会执行
    """
    job = Job(name=job_name)
    job.save()
    depend_task_ids = []
    for async_task_layer in async_task_chains:
        layer_ids = []
        for async_task in async_task_layer:
            task = Task(
                name=async_task.name,
                job_id=job.id,
                execute_func_name="{}.{}".format(async_task.__module__, async_task.__class__.__name__),
                execute_func=pickle.dumps(async_task),
                execute_params=b'',
            )
            task.save()

            for depend_task_id in depend_task_ids:
                task_depend = TaskDepend(
                    task_id=task.id,
                    depend_task_id=depend_task_id,
                )
                task_depend.save()

            layer_ids.append(task.id)
        depend_task_ids = layer_ids

    job.status = JobStatus.PENDING
    job.save()
    return job
